﻿// 2024/3/19: 首个记录，增加线控相关字段（基于vehicle-sample-v4.h 2023/10/12版本修改）
// 2024/3/24: 支持object-vehicle-sample-v1@x通道
// 2024/4/14: 基于新样本框架。枚举改为使用enum class
// 2024/7/3: 修正轮廓
// 2025/4/19: 新增大灯位置坐标和相对于地面俯仰角字段
// 2025/4/19: 修正fromSample
// 2025/6/3: 修正多余的字段定义

#ifndef VEHICLE_SAMPLE_V5_H
#define VEHICLE_SAMPLE_V5_H

#include "spadas.h"

namespace vehicle_sample_v5
{
	using namespace spadas;

	enum class GearPosition
	{
		Unknown = 0, // 未知
		Park = 1, // P档
		Reverse = 2, // R档
		Neutral = 3, // N档
		Drive = 4, // D档
	};

	enum class TurnState
	{
		Unknown = 0, // 未知
		None = 1, // 未打灯
		TurnLeft = 2, // 左转向灯
		TurnRight = 3, // 右转向灯
		Emergency = 4, // 双闪
	};

	enum class Horn
	{
		Unknown = 0, // 未知
		None = 1, // 不响
		Active = 2, // 响
	};

	enum class HeadLight
	{
		Unknown = 0, // 未知
		None = 1, // 未激活
		Near = 2, // 近光
		Far = 3, // 远光
	};

	enum class Wiper
	{
		Unknown = 0, // 未知
		None = 1, // 未激活
		Single = 2, // 单次
		Slow1 = 3, // 慢 1
		Slow2 = 4, // 慢 2
		Slow3 = 5, // 慢 3
		Slow4 = 6, // 慢 4
		Slow5 = 7, // 慢 5
		Medium = 8, // 中档
		Fast = 9, // 快档
	};

	struct VehicleSampleData
	{
		Double speed; // [kph] 本车车速
		OptionalDouble yawRate; // [deg/s] 横摆角速度
		OptionalDouble curvature; // [1/m] Turning left is positive, while the driving path is / 行驶曲率，左转为正，未来路径: y=(curvature/2)*(x^2)+(curvature)*(frontOverhang+wheelBase)*x
		Double kilometerAge; // [km] 总里程数
		OptionalDouble accelX; // [m/s2] 本车纵向加速度
		OptionalDouble accelY; // [m/s2] 本车横向加速度
		OptionalDouble jerkX; // [m/s3] 本车纵向急动度
		OptionalDouble jerkY; // [m/s3] 本车横向急动度
		Array<Point2D> trajectory; // 历史路径
		Array<Point2D> contour; // The first point and the last point are both (0,0), forming a closed curve (Constant) / 轮廓描述，以(0,0)开始，以(0,0)结束（常量）

		Double vehicleWidth; // [m] Constant / 车宽（常量）
		Double vehicleLength; // [m] Constant / 车长（常量）
		Double vehicleHeight; // [m] Constant / 车高（常量）
		Double steerAngleRatio; // Constant / 传动比（常量）
		Double wheelBase; // [m] Constant / 轴距（常量）
		Double rearTread; // [m] Constant / 轮距（常量）
		Double frontOverhang; // [m] Constant / 前悬（常量）

		OptionalDouble maxCurvature; // [1/m] Max absolute curvature value (Constant) / 最大行驶曲率，不分左右（常量）
		OptionalDouble maxAcceleration; // [m/s2] Max absolute longitudinal acceleration value for forward driving (Constant) / 前向行驶最大加速度（常量）
		OptionalDouble maxDeceleration; // [m/s2] Max absolute longitudinal deceleration value for forward driving (Constant) / 前向行驶最大减速度（常量）
		OptionalDouble maxAccelY; // [m/s2] Allowed max absolute lateral acceleration value (Constant) / 最大允许横向加速度，不分左右（常量）
		OptionalDouble maxSteerAngle; // [deg] Constant / 最大方向盘转角（常量）
		OptionalDouble maxSteerAngleRate; // [deg/s] Constant / 最大方向盘转角速度（常量）
		OptionalDouble brakeDeadZone; // [%] Constant / 刹车踏板死区（常量）
		OptionalDouble throttleDeadZone; // [%] Constant / 油门踏板死区（常量）
		OptionalDouble flMass; // [kg] Mass on front left wheel (Constant) / 左前轮上的质量（常量）
		OptionalDouble frMass; // [kg] Mass on front right wheel (Constant) / 右前轮上的质量（常量）
		OptionalDouble rlMass; // [kg] Mass on rear left wheel (Constant) / 左后轮上的质量（常量）
		OptionalDouble rrMass; // [kg] Mass on rear right wheel (Constant) / 右后轮上的质量（常量）
		OptionalDouble frontCorneringStiffness; // [N/rad] Sum of front left and front right wheel's cornering stiffness (Constant) / 前轮侧偏刚度，左右轮之和（常量）
		OptionalDouble rearCorneringStiffness; // [N/rad] Sum of rear left and rear right wheel's cornering stiffness (Constant) / 后轮侧偏刚度，左右轮之和（常量）

		OptionalDouble steerAngle; // [deg] 方向盘转角
		OptionalDouble steerAngleRate; // [deg/s] 方向盘转角速度
		OptionalDouble steerTorque; // [Nm] 方向盘力矩

		OptionalDouble brake; // [%] 刹车位置
		OptionalDouble throttle; // [%] 油门位置
		GearPosition gear; // 档位
		TurnState turn; // 转向灯
		Horn horn; // 喇叭
		HeadLight headLight; // 大灯
		Wiper wiper; // 雨刮

		OptionalDouble flSpeed; // [kph] Speed of front left wheel / 左前轮轮速
		OptionalDouble frSpeed; // [kph] Speed of front right wheel / 右前轮轮速
		OptionalDouble rlSpeed; // [kph] Speed of rear left wheel / 左后轮轮速
		OptionalDouble rrSpeed; // [kph] Speed of rear right wheel / 右后轮轮速

		OptionalDouble flAngle; // [deg] Direction of front left wheel / 左前轮朝向角
		OptionalDouble frAngle; // [deg] Direction of front right wheel / 右前轮朝向角

		OptionalDouble engineSpeed; // [rpm] 引擎转速
		OptionalDouble engineTorque; // [Nm] 引擎扭矩

		OptionalDouble frontEndLateralSpeed; // [m/s] 前保中心横向速度
		OptionalDouble rearEndLateralSpeed; // [m/s] 后保中心横向速度

		OptionalDouble flLightPosX; // [m] X Coordinate of front left light (the same as front right light) / 左前灯X坐标(即右前灯X坐标)
		OptionalDouble flLightPosY; // [m] Y Coordinate of front left light (negative value of front right light) / 左前灯Y坐标(右前灯Y坐标为其负值)
		OptionalDouble flLightPosZ; // [m] Z Coordinate of front left light (the same as front right light) / 左前灯Z坐标(即右前灯Z坐标)
		OptionalDouble rlLightPosX; // [m] X Coordinate of rear left light (the same as rear right light) / 左后灯X坐标(即右后灯X坐标)
		OptionalDouble rlLightPosY; // [m] Y Coordinate of rear left light (negative value of rear right light) / 左后灯Y坐标(右后灯Y坐标为其负值)
		OptionalDouble rlLightPosZ; // [m] Z Coordinate of rear left light (the same as rear right light) / 左后灯Z坐标(即右后灯Z坐标)

		OptionalDouble pitchToGround; // [deg] Vehicle's pitch angle to ground / 车辆相对于地面的俯仰角

		VehicleSampleData()
		{
			vehicleWidth = 1.9;
			vehicleLength = 4.6;
			vehicleHeight = 1.5;
			steerAngleRatio = 15;
			wheelBase = 2.8;
			rearTread = 1.6;
			frontOverhang = 0.9;
			gear = GearPosition::Unknown;
			turn = TurnState::Unknown;
			horn = Horn::Unknown;
			headLight = HeadLight::Unknown;
			wiper = Wiper::Unknown;
			speed = 0;
			kilometerAge = 0;
		}
	};

	class VehicleSample : public Object<class VehicleSampleVars>
	{
	public:
		SPADAS_TYPE("vehicle_sample_v5.VehicleSample")

		VehicleSample();
		FullTimestamp& timestamp();
		VehicleSampleData *operator ->();

		static String getSubjectProtocolName();
		static String getObjectProtocolName(UInt channel);
		SessionGeneralSample toGeneralSample();

		static Array<String> getSubjectProtocolNames();
		static Array<String> getObjectProtocolNames(UInt channel);
		Bool fromGeneralSample(String protocol, SessionGeneralSample generalSample);
	};
}

#endif
